package com.aim.common.util;

import java.io.*;
import java.util.StringTokenizer;

/**
 * @AUTO 文件工具类
 * @FILE FileUtil.java
 * @DATE 2017-8-30 下午6:10:10
 * @Author AIM
 */
public class FileUtil {

    /**
     * 获取项目的物理地址路径，截止到项目名称文件夹
     */
    public static String getWebSysPath() throws IOException {
        File file = new File(FileUtil.class.getResource("/").getPath());
        return file.getPath();
    }

    /**
     * 判断文件夹是否存在
     */
    public static void judeDirExists(String filePath) {
        File file = new File(filePath);
        judeDirExists(file);
    }

    /**
     * 判断文件夹是否存在
     */
    public static void judeDirExists(File file) {
        if (file.exists()) {
            if (file.isDirectory()) {
                System.out.println("dir exists ..." + file.getPath());
            } else {
                System.out.println("the same name file exists, can not create dir");
            }
        } else {
            System.out.println("dir not exists, create it ..." + file.getPath());
            boolean mkdir = file.mkdir();
            if (!mkdir) {
                file.mkdirs();
            }
        }
    }

    /**
     * 判断文件是否存在
     */
    public static void judeFileExists(String filePath) {
        File file = new File(filePath);
        judeFileExists(file);
    }

    /**
     * 判断文件是否存在
     */
    public static void judeFileExists(File file) {
        if (file.exists()) {
            System.out.println("file exists");
        } else {
            System.out.println("file not exists, create it ...");
            try {
                file.createNewFile();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    /**
     * 获取文件的扩展名,默认返回值空
     *
     * @param f 文件
     */
    public static String getExtension(File f) {
        return f != null ? getExtension(f.getName()) : "";
    }

    /**
     * 获取文件的扩展名,默认返回值空
     *
     * @param filename
     */
    public static String getExtension(String filename) {
        return getExtension(filename, "");
    }

    /**
     * 获取文件的扩展名
     *
     * @param filename
     * @param defExt   默认返回值
     */
    public static String getExtension(String filename, String defExt) {
        if ((filename != null) && (filename.length() > 0)) {
            int i = filename.lastIndexOf('.');

            if ((i > -1) && (i < filename.length() - 1)) {
                return filename.substring(i + 1);
            }
        }
        return defExt;
    }

    /**
     * 去掉文件的扩展名
     *
     * @param filename
     */
    public static String trimExtension(String filename) {
        if ((filename != null) && (filename.length() > 0)) {
            int i = filename.lastIndexOf('.');
            if ((i > -1) && (i < filename.length())) {
                return filename.substring(0, i);
            }
        }
        return filename;
    }

    /**
     * 遍历文件夹中文件
     *
     * @param filepath 文件路径
     * @return 返回file［］ 数组
     */
    public static File[] getFileList(String filepath) {
        File d = null;
        File list[] = null;
        /** 建立当前目录中文件的File对象 **/
        try {
            d = new File(filepath);
            if (d.exists()) {
                list = d.listFiles();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        /** 取得代表目录中所有文件的File对象数组 **/
        return list;
    }

    /**
     * 读取文本文件内容
     *
     * @param filePathAndName 带有完整绝对路径的文件名
     * @param encoding        文本文件打开的编码方式
     * @return 返回文本文件的内容
     */
    public static String readTxt(String filePathAndName, String encoding) throws IOException {
        encoding = encoding.trim();
        StringBuffer str = new StringBuffer("");
        String st = "";
        try {
            FileInputStream fs = new FileInputStream(filePathAndName);
            InputStreamReader isr;
            if (encoding.equals("")) {
                isr = new InputStreamReader(fs);
            } else {
                isr = new InputStreamReader(fs, encoding);
            }
            BufferedReader br = new BufferedReader(isr);
            try {
                String data = "";
                while ((data = br.readLine()) != null) {
                    str.append(data);
                }
            } catch (Exception e) {
                str.append(e.toString());
            }
            st = str.toString();
            if (st != null && st.length() > 1)
                st = st.substring(0, st.length() - 1);
        } catch (IOException es) {
            st = "";
        }
        return st;
    }

    /**
     * 新建目录
     *
     * @param folderPath 目录
     * @return 返回目录创建后的路径
     */
    public static String createFolder(String folderPath) {
        String txt = folderPath;
        try {
            File myFilePath = new File(txt);
            txt = folderPath;
            if (!myFilePath.exists()) {
                myFilePath.mkdir();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return txt;
    }

    /**
     * 多级目录创建
     *
     * @param folderPath 准备要在本级目录下创建新目录的目录路径例如
     *                   c:myf
     * @param paths      无限级目录参数
     *                   ，各级目录以单数线区分 例如 a|b|c
     * @return 返回创建文件后的路径
     */
    public static String createFolders(String folderPath, String paths) {
        String txts = folderPath;
        try {
            String txt;
            txts = folderPath;
            StringTokenizer st = new StringTokenizer(paths, "|");
            for (; st.hasMoreTokens(); ) {
                txt = st.nextToken().trim();
                if (txts.lastIndexOf("/") != -1) {
                    txts = createFolder(txts + txt);
                } else {
                    txts = createFolder(txts + txt + "/");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return txts;
    }

    /**
     * 新建文件
     *
     * @param filePathAndName 文本文件完整绝对路径及文件名
     * @param fileContent     文本文件内容
     */
    public static void createFile(String filePathAndName, String fileContent) {
        try {
            String filePath = filePathAndName;
            filePath = filePath.toString();
            File myFilePath = new File(filePath);
            if (!myFilePath.exists()) {
                myFilePath.createNewFile();
            }
            FileWriter resultFile = new FileWriter(myFilePath);
            PrintWriter myFile = new PrintWriter(resultFile);
            String strContent = fileContent;
            myFile.println(strContent);
            myFile.close();
            resultFile.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 有编码方式的文件创建
     *
     * @param filePathAndName 文本文件完整绝对路径及文件名
     * @param fileContent     文本文件内容
     * @param encoding        编码方式
     *                        例如 GBK 或者 UTF-8
     */
    public static void createFile(String filePathAndName, String fileContent, String encoding) {
        try {
            String filePath = filePathAndName;
            filePath = filePath.toString();
            File myFilePath = new File(filePath);
            if (!myFilePath.exists()) {
                myFilePath.createNewFile();
            }
            PrintWriter myFile = new PrintWriter(myFilePath, encoding);
            String strContent = fileContent;
            myFile.println(strContent);
            myFile.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 删除文件
     *
     * @param filePathAndName 文本文件完整绝对路径及文件名
     * @return Boolean 成功删除返回true遭遇异常返回false
     */
    public static boolean delFile(String filePathAndName) {
        boolean bea = false;
        try {
            String filePath = filePathAndName;
            File myDelFile = new File(filePath);
            if (myDelFile.exists()) {
                myDelFile.delete();
                bea = true;
            } else {
                bea = false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bea;
    }

    /**
     * 删除文件
     *
     * @param folderPath 文件夹完整绝对路径
     */
    public static void delFolder(String folderPath) {
        try {
            /** 删除完里面所有内容 **/
            delAllFile(folderPath);
            String filePath = folderPath;
            filePath = filePath.toString();
            File myFilePath = new File(filePath);
            /** 删除空文件夹 **/
            myFilePath.delete();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 删除指定文件夹下所有文件
     *
     * @param path 文件夹完整绝对路径
     */
    public static boolean delAllFile(String path) {
        boolean bea = false;
        File file = new File(path);
        if (!file.exists()) {
            return bea;
        }
        if (!file.isDirectory()) {
            return bea;
        }
        String[] tempList = file.list();
        File temp = null;
        for (int i = 0; i < tempList.length; i++) {
            if (path.endsWith(File.separator)) {
                temp = new File(path + tempList[i]);
            } else {
                temp = new File(path + File.separator + tempList[i]);
            }
            if (temp.isFile()) {
                temp.delete();
            }
            if (temp.isDirectory()) {
                /** 先删除文件夹里面的文件 **/
                delAllFile(path + "/" + tempList[i]);
                /** 再删除空文件 **/
                delFolder(path + "/" + tempList[i]);
                bea = true;
            }
        }
        return bea;
    }

    /**
     * 复制单个文件
     *
     * @param oldPathFile 准备复制的文件源
     * @param newPathFile 拷贝到新绝对路径带文件名
     */
    public static void copyFile(String oldPathFile, String newPathFile) {
        try {
            int byteread = 0;
            File oldfile = new File(oldPathFile);
            if (oldfile.exists()) {
                InputStream inStream = new FileInputStream(oldPathFile);
                FileOutputStream fs = new FileOutputStream(newPathFile);
                byte[] buffer = new byte[1444];
                while ((byteread = inStream.read(buffer)) != -1) {
                    fs.write(buffer, 0, byteread);
                }
                inStream.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 复制整个文件夹的内容
     *
     * @param oldPath 准备拷贝的目录
     * @param newPath 指定绝对路径的新目录
     */
    public static void copyFolder(String oldPath, String newPath) {
        try {
            /** 如果文件夹不存在 则建立新文件 **/
            new File(newPath).mkdirs();
            File a = new File(oldPath);
            String[] file = a.list();
            File temp = null;
            for (int i = 0; i < file.length; i++) {
                if (oldPath.endsWith(File.separator)) {
                    temp = new File(oldPath + file[i]);
                } else {
                    temp = new File(oldPath + File.separator + file[i]);
                }
                if (temp.isFile()) {
                    FileInputStream input = new FileInputStream(temp);
                    FileOutputStream output = new FileOutputStream(newPath + "/" + (temp.getName()).toString());
                    byte[] b = new byte[1024 * 5];
                    int len;
                    while ((len = input.read(b)) != -1) {
                        output.write(b, 0, len);
                    }
                    output.flush();
                    output.close();
                    input.close();
                }
                /** 如果是子文件 **/
                if (temp.isDirectory()) {
                    copyFolder(oldPath + "/" + file[i], newPath + "/" + file[i]);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 移动文件
     *
     * @param oldPath
     * @param newPath
     */
    public static void moveFile(String oldPath, String newPath) {
        copyFile(oldPath, newPath);
        delFile(oldPath);
    }

    /**
     * 移动目录
     *
     * @param oldPath 源路径
     * @param newPath 新路径
     */
    public static void moveFolder(String oldPath, String newPath) {
        copyFolder(oldPath, newPath);
        delFolder(oldPath);
    }

    /**
     * 建立一个可以追加的BufferedReader
     *
     * @param fileDir  文件路径
     * @param fileName 文件名
     */
    public static BufferedWriter getWriter(String fileDir, String fileName) {
        try {
            File f1 = new File(fileDir);
            if (!f1.exists()) {
                f1.mkdirs();
            }
            f1 = new File(fileDir, fileName);
            if (!f1.exists()) {
                f1.createNewFile();
            }
            BufferedWriter bw = new BufferedWriter(new FileWriter(f1.getPath(), true));
            return bw;
        } catch (Exception e) {
            System.out.println(e.getLocalizedMessage());
            return null;
        }
    }

    /**
     * 得到一个BufferedReader
     *
     * @param fileDir  文件路径
     * @param fileName 文件名
     * @param encoding 编码格式
     */
    public static BufferedReader getReader(String fileDir, String fileName, String encoding) {
        try {
            File file = new File(fileDir, fileName);
            InputStreamReader read = new InputStreamReader(new FileInputStream(file), encoding);
            BufferedReader br = new BufferedReader(read);
            return br;
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 将InputStream写入本地文件
     *
     * @param destination 写入本地目录
     * @param input       输入流
     */
    public static void writeToLocal(String destination, InputStream input) throws IOException {
        int index;
        byte[] bytes = new byte[1024];
        FileOutputStream downloadFile = new FileOutputStream(destination);
        while ((index = input.read(bytes)) != -1) {
            downloadFile.write(bytes, 0, index);
            downloadFile.flush();
        }
        downloadFile.close();
        input.close();
    }

    /**
     * 读取文件使uniCode编码转换为中文并输出
     */
    public static void file2file() {
        try {
            BufferedReader bre = null;
            String file = "F:/bui.js";
            bre = new BufferedReader(new FileReader(file));// 此时获取到的bre就是整个文件的缓存流
            BufferedWriter bw = new BufferedWriter(new FileWriter("F:/bui-new.js"));// 输出新的文件
            String str = null;
            while ((str = bre.readLine()) != null) {
                bw.write(ConverterUtils.unicodeToString(str) + "\r");
            }
            bw.flush();
            bw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获得指定文件的byte数组
     */
    public static byte[] getBytes(String filePath) {
        byte[] buffer = null;
        try {
            File file = new File(filePath);
            FileInputStream fis = new FileInputStream(file);
            ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);
            byte[] b = new byte[1024 * 5];
            int n;
            while ((n = fis.read(b)) != -1) {
                bos.write(b, 0, n);
            }
            fis.close();
            bos.close();
            buffer = bos.toByteArray();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return buffer;
    }
}